#include "VSActor.h"
#include "VSAIState.h"
#include "VSSteer.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
#include "VSWorld.h"
using namespace VSEngine2;

IMPLEMENT_RTTI_NoCreateFun(VSActor,VSObject)
BEGIN_ADD_PROPERTY(VSActor,VSObject)
//REGISTER_PROPERTY(m_fMaxVelocity,m_fMaxVelocity,VSProperty::F_SAVE_LOAD_CLONE | VSProperty::F_REFLECT_NAME);
// REGISTER_PROPERTY(m_LocalScale,Scale);
// REGISTER_PROPERTY(m_LocalRotate,Rotate);
END_ADD_PROPERTY
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_BEGIN(VSActor)
IMPLEMENT_INITIAL_NO_CLASS_FACTORY_END

VSActor::VSActor()
{

	m_pNode = NULL;
	m_pSceneMap = NULL;

	VSWorld::ms_pWorld->AddActor(this);
}
VSActor::~VSActor()
{
	m_pNode = NULL;
	m_pSceneMap = NULL;
	VSWorld::ms_pWorld->DeleteActor(this);
}
void VSActor::ProcessInput(unsigned int uiInputType,unsigned int uiEvent,unsigned int uiKey,int x, int y, int z)
{
	return;
}
void VSActor::SetWorldPos(const VSVector3 & Pos)
{
	if (m_pNode)
	{
		VSAVObject * pParent = m_pNode->GetParent();
		if (pParent)
		{
			VSTransform Inv;
			pParent->GetWorldTransform().Inverse(Inv);
			
			VSTransform NewWorld;
			NewWorld = m_pNode->GetWorldTransform();
			NewWorld.SetTranslate(Pos);
			VSTransform NewLocal;
			NewLocal.Product(NewWorld,Inv);
			m_pNode->SetLocalTransform(NewLocal);
			m_LocalPos = m_pNode->GetLocalTranslate();
		}
		else
		{
			SetLocalPos(Pos);
		}
		
	}
}
void VSActor::SetWorldScale(const VSVector3 &Scale)
{
	if (m_pNode)
	{
		VSAVObject * pParent = m_pNode->GetParent();
		if (pParent)
		{
			VSTransform Inv;
			pParent->GetWorldTransform().Inverse(Inv);

			VSTransform NewWorld;
			NewWorld = m_pNode->GetWorldTransform();
			NewWorld.SetScale(Scale);
			VSTransform NewLocal;
			NewLocal.Product(NewWorld,Inv);
			m_pNode->SetLocalTransform(NewLocal);
			m_LocalScale = m_pNode->GetLocalScale();
		}
		else
		{
			SetLocalScale(Scale);
		}

	}
}
void VSActor::SetWorldRotate(const VSMatrix3X3 & Rotate)
{
	if (m_pNode)
	{
		VSAVObject * pParent = m_pNode->GetParent();
		if (pParent)
		{
			VSTransform Inv;
			pParent->GetWorldTransform().Inverse(Inv);

			VSTransform NewWorld;
			NewWorld = m_pNode->GetWorldTransform();
			NewWorld.SetRotate(Rotate);
			VSTransform NewLocal;
			NewLocal.Product(NewWorld,Inv);
			m_pNode->SetLocalTransform(NewLocal);
			m_LocalRotate = m_pNode->GetLocalRotate();
		}
		else
		{
			SetLocalRotate(Rotate);
		}

	}
}
void VSActor::SetLocalPos(const VSVector3 & Pos)
{
	if (m_pNode)
	{
		m_LocalPos = Pos;
		m_pNode->SetLocalTranslate(Pos);
	}
}
void VSActor::SetLocalScale(const VSVector3 &Scale)
{
	if (m_pNode)
	{
		m_LocalScale = Scale;
		m_pNode->SetLocalScale(Scale);
	}
}
void VSActor::SetLocalRotate(const VSMatrix3X3 & Rotate)
{
	if (m_pNode)
	{
		m_LocalRotate = Rotate;
		m_pNode->SetLocalRotate(Rotate);
	}
}
VSVector3 VSActor::GetWorldPos()const
{
	if (m_pNode)
	{
		return m_pNode->GetWorldTranslate();
	}
	return m_LocalPos;
}
VSVector3 VSActor::GetWorldScale()const
{
	if (m_pNode)
	{
		return m_pNode->GetWorldScale();
	}
	return m_LocalScale;
}
VSMatrix3X3 VSActor::GetWorldRotate()const
{
	if (m_pNode)
	{
		return m_pNode->GetWorldRotate();
	}
	return m_LocalRotate;
}

VSVector3 VSActor::GetLocalPos()const
{
	return m_LocalPos;
}
VSVector3 VSActor::GetLocalScale()const
{
	return m_LocalScale;
}
VSMatrix3X3 VSActor::GetLocalRotate()const
{
	return m_LocalRotate;
}

bool VSActor::HandleMessage(VSMessage & Message)
{
	if (m_pFSM)
	{
		m_pFSM->HandleMessage(Message);
	}
	return true;
}
void VSActor::SetActorNode(VSAVObject * pNode)
{
	m_pNode = pNode;
}
void VSActor::Update(double dAppTime)
{

}
void VSActor::ForceUpdateTransform()
{
	if (m_pNode)
	{
		m_pNode->ForceUpdateTransform();
	}
}